package vr.mall.testTwo;

/**
 * 秒杀/MySQL redis分布式锁
 * 
 * @author sun
 */
public class SecKillForRedis {

	public static int goodsTotalNum = 100;

	public static void main(String[] args) {
		// 这块我们就不使用redis的那种集合插件的方式了，我们自己添加redis工具包
		// Jedis jedis = RedisUtil.getJedis();
		// 正规的秒杀系统流程是(如果使用redis)： 将商品库存存入redis中，然后增加redis分布式锁，
		// 当有用户抢到了商品后，会使用mq消息队列通知数据库进行库存减1（库存虽然存到redis中，但是还是要以数据库库存为准）
		// 我们这里只是演示redis分布式锁的使用，就不增加mq了，后期我会再专门整理一片redis+mq的使用方式的

		Integer num = 99;
		SecKillRedis sk = new SecKillRedis(num); // 模拟120个人抢购。 模拟120人分别在不同的服务器进行发起请求
		for (int i = 1; i <= 100; i++) {
			new Thread(sk, i + " 号人").start();
		}

		System.out.println("111");
	}
}

class SecKillRedis implements Runnable {

	private int num = 0;

	public SecKillRedis(int num) {
		this.num = num;
	}

	@Override
	public void run() { // 设置10000毫秒锁失效，避免出现死锁 //这里的redis
		// value值我们就用线程名字了，当然也可以使用requestId等，只要保证每个用户的唯一即可，因为在释放锁的时候需要校验这个值
		while (num > 0) {
			if (RedisTool.tryLock("lock_sun", Thread.currentThread().getName(), 100)) {
				System.out.println(Thread.currentThread().getName() + " 抢到了第"
						+ (SecKillForRedis.goodsTotalNum - num) + " 件商品；");
				num-=1;
				return;
			}
		}
		System.err.println(Thread.currentThread().getName() + " 太悲剧了，没抢到商品...");
	}

}
